/*
# MIAHX© 交互框架信息表示模型的 FastDDS 参与者的 C++ 实现

**模块：MIAHX© / 框架基础服务层（FFST） / 交互框架信息表示模型（IFIRM）**

Version: 0.4.10
Last updated: October 16, 2024

## Contributor(s)
* YAO Naiming <[naiming@iscas.ac.cn](mailto:naiming@iscas.ac.cn)>

## Change log
### v0.4.10
- .16: [更新] 新增注释，调整 include 逻辑
- .15: [更新] 版本同步至 Python 版v0.4.10.14
### v0.4.7
- .26: [新增] 初始实现

---
Copyright © 2024-2025 MIAHX Contributors, ISCAS, and ASIC. All Rights Reserved.
Licensed under Apache-2.0.
*/

#pragma once

#include "../nlohmann/json.hpp"
#include "export.h"
#include "topic.h"

#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>

#include "MiahxFastDDSTypes.h"
#include "MiahxFastDDSTypesPubSubTypes.h"

using json = nlohmann::json;
using namespace eprosima::fastdds::dds;


enum Domains : uint32_t {
    MIAHX = 57
};

enum ParticipantQosTypes {
    PARTICIPANT_QOS_TYPES_DEFAULT = 0,
    PARTICIPANT_QOS_TYPES_LARGE_DATA = 1
};

enum PublisherQosTypes {
    PUB_QOS_TYPES_DEFAULT = 0
};


enum SubscriberQosTypes {
    SUB_QOS_TYPES_DEFAULT = 0
};

typedef struct topic_description {
    Topic *topic;
    TopicDataType *topic_data_type;
} topic_description;


/**
 * @brief FastDDS 参与者接口
 */
class Participant {
public:
    /**
     * @brief 构造函数
     *
     * @param domain 领域ID，默认为 57
     * @param qos_type 服务质量类型
     */
    MIAHX_WRAPPER_API
    explicit Participant(Domains domain = Domains::MIAHX,
                         ParticipantQosTypes qos_type = ParticipantQosTypes::PARTICIPANT_QOS_TYPES_DEFAULT);

    /**
     * @brief 析构函数
     */
    MIAHX_WRAPPER_API
    ~Participant();

    /**
     * @brief 新增主题
     *
     * @param topic_name 主题名称，可从 Topics.h 中选择
     * @param topic_data_type 主题数据类型
     * @return 主题对象
     */
    MIAHX_WRAPPER_API
    Topic *add_topic(const std::string &topic_name, TopicDataType *topic_data_type);

    /**
     * @brief 新增消息发布者
     *
     * @param qos_type 服务质量
     * @return 发布者对象
     */
    MIAHX_WRAPPER_API
    Publisher *add_publisher(PublisherQosTypes qos_type = PublisherQosTypes::PUB_QOS_TYPES_DEFAULT);

    /**
     * @brief 新增订阅者
     *
     * @param qos_type 服务质量
     * @return 订阅者对象
     */
    MIAHX_WRAPPER_API
    Subscriber *add_subscriber(SubscriberQosTypes qos_type = SubscriberQosTypes::SUB_QOS_TYPES_DEFAULT);

public:
    DomainId_t domain;

private:
    recursive_mutex _lock;
    DomainParticipant *_participant;
    std::map<string, topic_description> _topics;
    std::map<PublisherQosTypes, Publisher *> _pubs;
    std::map<SubscriberQosTypes, Subscriber *> _subs;
};
